from django.urls import reverse_lazy
from django.utils.text import slugify
from django.utils.translation import gettext as _

from netbox.choices import ButtonColorChoices
from netbox.navigation import MenuGroup

__all__ = (
    'PluginMenu',
    'PluginMenuButton',
    'PluginMenuItem',
)


class PluginMenu:
    icon_class = 'mdi mdi-puzzle'

    def __init__(self, label, groups, icon_class=None):
        self.label = label
        self.groups = [
            MenuGroup(label, items) for label, items in groups
        ]
        if icon_class is not None:
            self.icon_class = icon_class

    @property
    def name(self):
        return slugify(self.label)


class PluginMenuItem:
    """
    This class represents a navigation menu item. This constitutes primary link and its text, but also allows for
    specifying additional link buttons that appear to the right of the item in the van menu.

    Links are specified as Django reverse URL strings suitable for rendering via {% url item.link %}.
    Alternatively, a pre-generated url can be set on the object which will be rendered literally.
    Buttons are each specified as a list of PluginMenuButton instances.
    """
    permissions = []
    buttons = []
    _url = None

    def __init__(
        self, link, link_text, auth_required=False, staff_only=False, permissions=None, buttons=None
    ):
        self.link = link
        self.link_text = link_text
        self.auth_required = auth_required
        self.staff_only = staff_only
        if link:
            self._url = reverse_lazy(link)
        if permissions is not None:
            if type(permissions) not in (list, tuple):
                raise TypeError(_("Permissions must be passed as a tuple or list."))
            self.permissions = permissions
        if buttons is not None:
            if type(buttons) not in (list, tuple):
                raise TypeError(_("Buttons must be passed as a tuple or list."))
            self.buttons = buttons

    @property
    def url(self):
        return self._url

    @url.setter
    def url(self, value):
        self._url = value


class PluginMenuButton:
    """
    This class represents a button within a PluginMenuItem. Note that button colors should come from
    ButtonColorChoices.
    """
    color = ButtonColorChoices.DEFAULT
    permissions = []
    _url = None

    def __init__(self, link, title, icon_class, color=None, permissions=None):
        self.link = link
        self.title = title
        self.icon_class = icon_class
        if link:
            self._url = reverse_lazy(link)
        if permissions is not None:
            if type(permissions) not in (list, tuple):
                raise TypeError(_("Permissions must be passed as a tuple or list."))
            self.permissions = permissions
        if color is not None:
            if color not in ButtonColorChoices.values():
                raise ValueError(_("Button color must be a choice within ButtonColorChoices."))
            self.color = color

    @property
    def url(self):
        return self._url

    @url.setter
    def url(self, value):
        self._url = value
